package org.jsola.contract.web;

import org.jsola.contract.common.FileHelper;
import org.jsola.contract.common.PdfUtil;
import org.jsola.contract.common.WkPdfHelper;
import org.jsola.contract.constant.ContractConstants;
import org.jsola.contract.dto.TemplateAddDTO;
import org.jsola.contract.dto.TemplatePreviewDTO;
import org.jsola.contract.dto.TemplateUpdateDTO;
import org.jsola.contract.query.TemplateQuery;
import org.jsola.contract.service.ISignService;
import org.jsola.contract.service.ITemplateService;
import org.jsola.contract.vo.TemplateListVO;
import org.jsola.contract.vo.TemplateVO;
import org.jsola.core.Page;
import org.jsola.core.Result;
import org.jsola.exception.ParamException;
import org.jsola.file.common.FileUtil;
import org.jsola.file.core.FileProperties;
import org.jsola.user.core.TokenUser;
import org.jsola.user.core.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;

import javax.validation.Valid;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 合同模板
 *
 * @author JanusMix
 */
@RestController("contractTemplateController")
@RequestMapping(ContractConstants.API_PATH + "/v1/templates")
public class TemplateController implements ITemplateControllerAPI {

    @Autowired
    private ITemplateService templateService;
    @Autowired
    private FileProperties fileProperties;
    @Autowired
    private ISignService signService;

    @Override
    @PostMapping
    public Result<TemplateVO> save(@Valid @RequestBody TemplateAddDTO templateAddDTO) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 新增合同模板权限校验

        return Result.success(
                templateService.save(templateAddDTO, tokenUser)
        );
    }


    @Override
    @PutMapping
    public Result<Integer> update(@Valid @RequestBody TemplateUpdateDTO templateUpdateDTO) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 修改合同模板权限校验

        int count = templateService.update(templateUpdateDTO, tokenUser);
        if (count == 0) {
            throw new ParamException("更新失败，请刷新页面后重试");
        }
        return Result.success(count);
    }


    @Override
    @DeleteMapping(value = "/{templateId}")
    public Result<Integer> delete(@PathVariable Long templateId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 彻底删除合同模板权限校验

        int count = templateService.deleteByIds(tokenUser, templateId);
        if (count == 0) {
            throw new ParamException("删除失败，请刷新页面后重试");
        }
        return Result.success(count);
    }

    @Override
    @DeleteMapping
    public Result<Integer> deleteBatch(@RequestBody Long[] templateIds) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 批量彻底删除合同模板权限校验

        int count = templateService.deleteByIds(tokenUser, templateIds);
        if (count == 0) {
            throw new ParamException("删除失败，请刷新页面后重试");
        }
        return Result.success(count);
    }

    @Override
    @GetMapping(value = "/{templateId}")
    public Result<TemplateVO> findById(@PathVariable Long templateId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看合同模板权限校验

        return Result.success(
                templateService.selectById(templateId, tokenUser.getSiteId())
        );
    }

    @Override
    @GetMapping(value = "/listAll")
    public Result<List<TemplateListVO>> listAll(@Valid TemplateQuery templateQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看合同模板权限校验

        return Result.success(
                templateService.select(templateQuery, tokenUser.getSiteId())
        );
    }


    @Override
    @GetMapping
    public Result<Page<TemplateListVO>> page(@Valid TemplateQuery templateQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                templateService.selectPage(templateQuery, tokenUser.getSiteId())
        );
    }

    @Override
    @PostMapping("/preview")
    public ResponseEntity<Resource> viewFile(@Valid @RequestBody TemplatePreviewDTO templatePreviewDTO) {

        String fileName = templatePreviewDTO.getFileName() + ".pdf";
        String filePath = fileProperties.getTempPath() + File.separator + fileName;
        byte[] bytes = new byte[]{};
        //创建文件
        FileHelper.saveFileByStream(bytes, filePath);
        //富文本反转义
        String content = templatePreviewDTO.getContent() == null ? " " : templatePreviewDTO.getContent();
        content = content.replaceAll("#<", "#&nbsp;<");
        content = HtmlUtils.htmlUnescape(content);
        if (templatePreviewDTO.getReplace() != null && templatePreviewDTO.getReplace()) {
            String REG_A = "<a[^>]*?>";
            Pattern A_REG_PATTERN = Pattern.compile(REG_A, Pattern.CASE_INSENSITIVE);
            Matcher contentMatcher = A_REG_PATTERN.matcher(content);
            content = contentMatcher.replaceAll("").replaceAll("</a>", "");
        }

        if (!CollectionUtils.isEmpty(templatePreviewDTO.getVariableList())) {
            content = signService.substitutionVariable(content, templatePreviewDTO.getVariableList(), new ArrayList<>());
        }
        //文件根据内容转为pdf
        WkPdfHelper.exportPdf(filePath, content);
        //写入到输出流
        FileSystemResource resource = new FileSystemResource(filePath);
        if (!resource.exists()) {
            throw new ParamException("文件不存在或已被删除");
        }
        // 文件名编码
        String filenames = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        MediaType mimeType = FileUtil.guessMimeType(fileName);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "inline;filename=\"" + filenames + "\"")
                .contentType(mimeType)
                .body(resource);
    }

    @Override
    @PostMapping("/previewJpg")
    public ResponseEntity<Resource> viewJpgFile(@Valid @RequestBody TemplatePreviewDTO templatePreviewDTO) {

        String fileName = templatePreviewDTO.getFileName() + ".pdf";
        String filePath = fileProperties.getTempPath() + File.separator + fileName;
        byte[] bytes = new byte[]{};
        //创建文件
        FileHelper.saveFileByStream(bytes, filePath);
        //富文本反转义
        String content = HtmlUtils.htmlUnescape(templatePreviewDTO.getContent() == null ? " " : templatePreviewDTO.getContent());
        if (templatePreviewDTO.getReplace() != null && templatePreviewDTO.getReplace()) {
            String REG_A = "<a[^>]*?>";
            Pattern A_REG_PATTERN = Pattern.compile(REG_A, Pattern.CASE_INSENSITIVE);
            Matcher contentMatcher = A_REG_PATTERN.matcher(content);
            content = contentMatcher.replaceAll("").replaceAll("</a>", "");
        }

        if (!CollectionUtils.isEmpty(templatePreviewDTO.getVariableList())) {
            content = signService.substitutionVariable(content, templatePreviewDTO.getVariableList(), new ArrayList<>());
        }
        //文件根据内容转为pdf
        WkPdfHelper.exportPdf(filePath, content);
        // 生成jpg
        String fileJpgName = System.currentTimeMillis() + ".jpg";
        String fileJpgPath = fileProperties.getTempPath() + File.separator + fileJpgName;
        PdfUtil.pdf2multiImage(filePath, fileJpgPath, 80);

        //写入到输出流
        FileSystemResource resource = new FileSystemResource(fileJpgPath);
        if (!resource.exists()) {
            throw new ParamException("文件不存在或已被删除");
        }
        // 文件名编码
        String filenames = new String(fileJpgName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        MediaType mimeType = FileUtil.guessMimeType(fileJpgName);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "inline;filename=\"" + filenames + "\"")
                .contentType(mimeType)
                .body(resource);
    }

    @Override
    @PostMapping("/previewJpgPath")
    public Result<String> viewJpgPath(@Valid @RequestBody TemplatePreviewDTO templatePreviewDTO) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                templateService.viewJpgPath(templatePreviewDTO, tokenUser)
        );
    }


}

